/*
 *
 *  * Copyright (c) 2016. For Intelligent Group.
 *
 */

package com.intelligent.ispc.client.core.view.analysis;

import com.google.common.collect.Lists;
import com.intelligent.ispc.client.core.controller.GlobalSearchController;
import com.intelligent.ispc.client.core.modal.SearchCsvTableModel;
import com.intelligent.ispc.client.core.view.AbstractPanel;
import com.intelligent.ispc.client.event.AnalysisFileChangeEvent;
import com.intelligent.ispc.client.event.SearchParamsChangeEvent;
import com.intelligent.ispc.client.ex.JTextFieldEx;
import com.intelligent.ispc.client.utils.*;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.common.utils.ResourceBundleUtils;
import com.intelligent.ispc.common.utils.StringUtils;
import com.intelligent.ispc.core.dto.FileDataDto;
import com.intelligent.ispc.core.dto.KeyValueDto;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

/**
 * Created by Peter on 2016/9/2.
 */
public class AnalysisFilePanel extends AbstractPanel {
    private SearchCsvTableModel csvModel;
    private GlobalSearchController globalSearchController;
    private String moduleKey;

    /**
     * Constructor
     *
     * @param module current component
     */
    public AnalysisFilePanel(String module) {
        this.moduleKey = module;
        initComponents();
    }

    @Override
    public void initDataSource() {
        globalSearchController = ApplicationBeanUtils.getBean(GlobalSearchController.class);
        csvModel.setData(globalSearchController.findFiles());

        csvTable.setRowSorter(csvSorter);
        csvTable.setModel(csvModel);
    }

    @Override
    public void initView() {
        csvTable.getTableHeader().setVisible(false);
        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setPreferredSize(new Dimension(0, 0));
        csvTable.getTableHeader().setDefaultRenderer(renderer);

        //set columns width;
        csvTable.getColumnModel().getColumn(0).setPreferredWidth(10);
        csvTable.getColumnModel().getColumn(0).setMaxWidth(50);
        csvTable.getColumnModel().getColumn(0).setMinWidth(30);
        csvTable.getColumnModel().getColumn(1).setPreferredWidth(100);
        csvTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
        csvFilter.setPlaceHolder("Filter");
    }

    /**
     * Initialize compoment
     */
    public void initComponents() {
        final int textFieldSize = 15;
        filePanel = new JPanel();
        buttonPanel = new JPanel();
        csvTable = new JTable();
        csvFilter = new JTextFieldEx(textFieldSize);
        analysisButton = new JButton("Analysis");
        importButton = new JButton("Import");
        deleteButton = new JButton("Delete");
        emptyAllButton = new JButton("Empty All");
        reloadButton = new JButton("Reload");
        String[] columns = new String[]{"name", "path"};
        csvModel = new SearchCsvTableModel(columns);
        csvSorter = new TableRowSorter(csvModel);

        //init File Panel
        JScrollPane csvTableScroll = new JScrollPane();
        final Dimension csvTableScrollSize = new Dimension(0, 100);
        csvTableScroll.setPreferredSize(csvTableScrollSize);
        csvTableScroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        csvTableScroll.setViewportView(csvTable);
        filePanel.setLayout(new GridBagLayout());
        filePanel.setBorder(BorderFactory.createTitledBorder("CSV"));
        filePanel.add(csvTableScroll, new GBC(0, 0).setFill(GBC.BOTH).setWeight(100, 100));
        filePanel.add(csvFilter, new GBC(0, 1).setFill(GBC.HORIZONTAL));

        //init Button Panel
        buttonPanel.setLayout(new GridBagLayout());
        buttonPanel.add(analysisButton, new GBC(0, 0, 2, 1).setFill(GBC.HORIZONTAL).setWeight(100, 0));
        buttonPanel.add(importButton, new GBC(0, 1).setFill(GBC.HORIZONTAL).setWeight(100, 0));
        buttonPanel.add(deleteButton, new GBC(1, 1).setFill(GBC.HORIZONTAL).setWeight(100, 0));
        buttonPanel.add(emptyAllButton, new GBC(0, 2).setFill(GBC.HORIZONTAL).setWeight(100, 0));
        buttonPanel.add(reloadButton, new GBC(1, 2).setFill(GBC.HORIZONTAL).setWeight(100, 0));

        this.setLayout(new GridBagLayout());
        this.setBorder(BorderFactory.createEmptyBorder());
        this.add(filePanel, new GBC(0, 0).setFill(GBC.BOTH).setAnchor(GBC.NORTH).setWeight(100, 100));
        this.add(buttonPanel, new GBC(0, 1).setFill(GBC.BOTH).setAnchor(GBC.NORTH));

        initComponentsListener();
    }

    /**
     * Get the selected CSV files
     *
     * @return keyValueDtos
     */
    public List<KeyValueDto> getSelectedFiles() {
        List<FileDataDto> fileDataDtos = csvModel.getData();
        List<KeyValueDto> keyValueDtos = Lists.newArrayList();
        if (fileDataDtos != null) {
            for (int i = 0; i < fileDataDtos.size(); i++) {
                if (fileDataDtos.get(i).isCheck()) {
                    KeyValueDto keyValueDto = new KeyValueDto();
                    keyValueDto.setKey(fileDataDtos.get(i).getName());
                    keyValueDto.setValue(fileDataDtos.get(i).getSavePath());
                    keyValueDtos.add(keyValueDto);
                }
            }
        }
        return keyValueDtos;
    }

    private void initComponentsListener() {
        //init components listener
        csvTable.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int row = ((JTable) e.getSource()).rowAtPoint(e.getPoint());
                int rowIndex = ((JTable) e.getSource()).convertRowIndexToModel(row);

                if (csvModel.getDataAtIndex(rowIndex).isCheck()) {
                    csvModel.getDataAtIndex(rowIndex).setCheck(false);
                } else {
                    csvModel.getDataAtIndex(rowIndex).setCheck(true);
                }
                EventBusUtils.post(new SearchParamsChangeEvent(moduleKey, SearchParamsChangeEvent.TYPE_FILE, csvModel.isValidCatchData()));
                csvTable.updateUI();
            }
        });
        importButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<KeyValueDto> keyValueDtos = Lists.newArrayList();
                String regType = ".?(?:csv)";
                String[] selectedFiles = FileUtils.fileSelect(AnalysisFilePanel.this, keyValueDtos, regType);
                if (!StringUtils.isBlank(selectedFiles[0]) && keyValueDtos != null) {
                    if (!keyValueDtos.isEmpty()) {
                        List<String> existNames = globalSearchController.validateFiles(keyValueDtos);
                        String alertMsg = " ";
                        if (existNames != null && !existNames.isEmpty()) {
                            for (int i = keyValueDtos.size() - 1; i >= 0; i--) {
                                if (existNames.contains(keyValueDtos.get(i).getKey())) {
                                    alertMsg += keyValueDtos.get(i).getKey() + System.getProperty("line.separator");
                                    keyValueDtos.remove(i);
                                }
                            }
                        }
                        globalSearchController.importFile(keyValueDtos);
                        csvModel.setData(globalSearchController.findFiles());

                        if (StringUtils.isNotBlank(selectedFiles[1])) {
                            alertMsg += selectedFiles[1];
                        }
                        if (StringUtils.isNotBlank(alertMsg)) {
                            String massage = ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_FILE_ALREADY_EXISTED) + System.getProperty("line.separator") + alertMsg;
                            String alertMessage = "";
                            final int len = 50;
                            int rowCount = massage.length() / len;
                            for (int i = 0; i < rowCount; i++) {
                                alertMessage += massage.substring(i * len, i * len + len - 1) + System.getProperty("line.separator");
                            }
                            if (rowCount * len < massage.length()) {
                                alertMessage += massage.substring(rowCount * len, massage.length());
                            }
                            AppMessageFactory.showWarningDialog(alertMessage);
                        }

                    }
                }
            }
        });
        analysisButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    if (csvModel.getCheckedPaths() != null && !csvModel.getCheckedPaths().isEmpty()) {
                        csvModel.setSelectedDataCache(csvModel.getSelectedFile());
                        globalSearchController.checkFile(csvModel.getData());
                        EventBusUtils.post(new AnalysisFileChangeEvent(moduleKey, csvModel.getCheckedPaths()));
                    } else {
                        throw new UIException(com.intelligent.ispc.client.utils.ExceptionMessages.EXCEPTION_SPC_NO_SELECT_FILE);
                    }
                } catch (UIException ex) {
                    AppMessageFactory.showWarningDialog(ResourceBundleUtils.getString(ex.getMessage()));
                }
            }
        });

        csvFilter.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                update(e);
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                update(e);
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                update(e);
            }

            private void update(DocumentEvent e) {
                String value = csvFilter.getText();
                if (value.length() == 0) {
                    csvSorter.setRowFilter(null);
                } else {
                    csvSorter.setRowFilter(RowFilter.regexFilter(value, 1));
                }
            }
        });

        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                List<FileDataDto> data = csvModel.getData();
                if (csvModel.getCheckedPaths() != null && !csvModel.getCheckedPaths().isEmpty()) {
                    int optionFlag = AppMessageFactory.showConfirmDialog(ResourceBundleUtils.getString(com.intelligent.ispc.client.utils.ExceptionMessages.EXCEPTION_GLOBAL_IS_DELETE));
                    if (optionFlag == 0) {
                        List<FileDataDto> param = Lists.newArrayList();
                        for (FileDataDto dto : data) {
                            if (dto.isCheck()) {
                                param.add(dto);
                            }
                        }
                        globalSearchController.deleteFiles(param);
                        csvModel.setData(globalSearchController.findFiles());
                        EventBusUtils.post(new AnalysisFileChangeEvent(moduleKey, null));
                    }
                } else {
                    AppMessageFactory.showWarningDialog(ResourceBundleUtils.getString(com.intelligent.ispc.client.utils.ExceptionMessages.EXCEPTION_SPC_NO_SELECT_FILE));
                }
            }
        });

        emptyAllButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int optionFlag = AppMessageFactory.showConfirmDialog(ResourceBundleUtils.getString(com.intelligent.ispc.client.utils.ExceptionMessages.EXCEPTION_GLOBAL_IS_EMPTY));
                if (optionFlag == 0) {
                    List<FileDataDto> param = ((SearchCsvTableModel) csvTable.getModel()).getData();
                    globalSearchController.deleteFiles(param);
                    csvModel.setData(globalSearchController.findFiles());
                    EventBusUtils.post(new AnalysisFileChangeEvent(moduleKey, csvModel.getCheckedPaths()));
                    csvFilter.setText("");
                }
            }
        });

        reloadButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                List<FileDataDto> param = globalSearchController.reloadFile();
                csvModel.setData(param);
                EventBusUtils.post(new AnalysisFileChangeEvent(moduleKey, null));
                csvFilter.setText("");
            }
        });
    }


    private JTable csvTable;
    private JTextFieldEx csvFilter;
    private TableRowSorter csvSorter;
    private JPanel filePanel;
    private JPanel buttonPanel;
    private JButton analysisButton;
    private JButton importButton;
    private JButton deleteButton;
    private JButton emptyAllButton;
    private JButton reloadButton;
}
